package com.lds.erp.util;

import org.springframework.util.Assert;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Random;

public class DateUtil {

	/** 年月日时分秒(无下划线) yyyyMMddHHmmssSSS */
	public static final String PATTERN_DTLONG = "yyyyMMddHHmmss";



	public static final String PATTERN_STANDARD = "yyyy-MM-dd HH:mm:ss";

	public static final String PATTERN_DATE = "yyyy-MM-dd";

	public static final String PATTERN_SECOND = "ssSSS";

	/**
	 * 获取昨天0.00的日期
	 * 
	 * @return
	 */
	public static Date getYesterdayStart() {

		Calendar Cal = Calendar.getInstance();
		Cal.setTime(new Date());
		Cal.add(Calendar.HOUR_OF_DAY, -24);

		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PATTERN_DATE);
		SimpleDateFormat simpleDate = new SimpleDateFormat(PATTERN_STANDARD);
		try {
			return simpleDate.parse(simpleDateFormat.format(Cal.getTime()) + " 00:00:00");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;

	}
	/**
	 * 获取系统当前时间 new Date();
	 * 
	 * @return
	 */
	public static Date getDate() {

		return new Date();
	}

	/**
	 * 获取昨天23:59:59的日期
	 * 
	 * @return
	 */
	public static Date getYesterdayEnd() {

		Calendar Cal = Calendar.getInstance();
		Cal.setTime(new Date());
		Cal.add(Calendar.HOUR_OF_DAY, -24);
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PATTERN_DATE);
		SimpleDateFormat simpleDate = new SimpleDateFormat(PATTERN_STANDARD);

		try {
			return simpleDate.parse(simpleDateFormat.format(Cal.getTime()) + " 23:59:59");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;

	}
	/**
	 * 获取今天日期
	 * 
	 * @return
	 */
	public static Date getToday() {

		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PATTERN_DATE);

		try {
			return simpleDateFormat.parse(simpleDateFormat.format(new Date()));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;

	}

	/**
	 * 获得服务器当前时间字符串
	 * 
	 * @author NIUBIN
	 * @date 2015年12月11日
	 */
	public static String getTodayStr(String pattern) {
		if (pattern == null || "".equals(pattern)) {
			pattern = PATTERN_DTLONG; // pattern
		}
		return new SimpleDateFormat(pattern).format(new Date());
	}

	/**
	 * 
	 * 获得一个日期上个月的日期字符串
	 * 
	 * @author NIUBIN
	 * @date 2015年12月11日
	 */
	public static String getLastMonthStr(Date date, String pattern) {
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		if (null == date) {
			date = new Date();
		}
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, -1);
		return sdf.format(cal.getTime());
	}

	public static String timestamp2String(Timestamp timestamp, String pattern) {
		if (timestamp == null) {
			throw new IllegalArgumentException("timestamp null illegal");
		}
		if (pattern == null || pattern.equals("")) {
			pattern = PATTERN_STANDARD;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		return sdf.format(new Date(timestamp.getTime()));
	}

	public static String date2String(Date date, String pattern) {
		if (date == null) {
			throw new IllegalArgumentException("timestamp null illegal");
		}
		if (pattern == null || pattern.equals("")) {
			pattern = PATTERN_STANDARD;
			;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		return sdf.format(date);
	}

	public static String getDataSecond() {
		SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		return fmt.format(new Date());
	}

	public static Timestamp currentTimestamp() {
		return new Timestamp(new Date().getTime());
	}

	public static String currentTimestamp2String(String pattern) {
		return timestamp2String(currentTimestamp(), pattern);
	}

	public static Timestamp string2Timestamp(String strDateTime, String pattern) {
		if (strDateTime == null || strDateTime.equals("")) {
			throw new IllegalArgumentException("Date Time Null Illegal");
		}
		if (pattern == null || pattern.equals("")) {
			pattern = PATTERN_STANDARD;
		}

		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		Date date = null;
		try {
			date = sdf.parse(strDateTime);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
		return new Timestamp(date.getTime());
	}

	public static Date string2Date(String strDate, String pattern) {
		if (strDate == null || strDate.equals("")) {
			throw new RuntimeException("str date null");
		}
		if (pattern == null || pattern.equals("")) {
			pattern = DateUtil.PATTERN_DATE;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		Date date = null;

		try {
			date = sdf.parse(strDate);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
		return date;
	}

	public static String stringToYear(String strDest) {
		if (strDest == null || strDest.equals("")) {
			throw new IllegalArgumentException("str dest null");
		}

		Date date = string2Date(strDest, DateUtil.PATTERN_DATE);
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return String.valueOf(c.get(Calendar.YEAR));
	}

	public static String stringToMonth(String strDest) {
		if (strDest == null || strDest.equals("")) {
			throw new IllegalArgumentException("str dest null");
		}

		Date date = string2Date(strDest, DateUtil.PATTERN_DATE);
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		// return String.valueOf(c.get(Calendar.MONTH));
		int month = c.get(Calendar.MONTH);
		month = month + 1;
		if (month < 10) {
			return "0" + month;
		}
		return String.valueOf(month);
	}

	public static String stringToDay(String strDest) {
		if (strDest == null || strDest.equals("")) {
			throw new IllegalArgumentException("str dest null");
		}

		Date date = string2Date(strDest, DateUtil.PATTERN_DATE);
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		// return String.valueOf(c.get(Calendar.DAY_OF_MONTH));
		int day = c.get(Calendar.DAY_OF_MONTH);
		if (day < 10) {
			return "0" + day;
		}
		return "" + day;
	}

	public static Date getFirstDayOfMonth(Calendar c) {
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH);
		int day = 1;
		c.set(year, month, day, 0, 0, 0);
		return c.getTime();
	}

	public static Date getLastDayOfMonth(Calendar c) {
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH) + 1;
		int day = 1;
		if (month > 11) {
			month = 0;
			year = year + 1;
		}
		c.set(year, month, day - 1, 0, 0, 0);
		return c.getTime();
	}

	public static String date2GregorianCalendarString(Date date) {
		if (date == null) {
			throw new IllegalArgumentException("Date is null");
		}
		long tmp = date.getTime();
		GregorianCalendar ca = new GregorianCalendar();
		ca.setTimeInMillis(tmp);
		try {
			XMLGregorianCalendar t_XMLGregorianCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(ca);
			return t_XMLGregorianCalendar.normalize().toString();
		} catch (DatatypeConfigurationException e) {
			e.printStackTrace();
			throw new IllegalArgumentException("Date is null");
		}

	}

	public static boolean compareDate(Date firstDate, Date secondDate) {
		if (firstDate == null || secondDate == null) {
			throw new RuntimeException();
		}

		String strFirstDate = date2String(firstDate, "yyyy-MM-dd");
		String strSecondDate = date2String(secondDate, "yyyy-MM-dd");
		if (strFirstDate.equals(strSecondDate)) {
			return true;
		}
		return false;
	}

	public static Date getStartTimeOfDate(Date currentDate) {
		Assert.notNull(currentDate);
		String strDateTime = date2String(currentDate, "yyyy-MM-dd") + " 00:00:00";
		return string2Date(strDateTime, "yyyy-MM-dd hh:mm:ss");
	}

	public static Date getEndTimeOfDate(Date currentDate) {
		Assert.notNull(currentDate);
		String strDateTime = date2String(currentDate, "yyyy-MM-dd") + " 23:59:59";
		return string2Date(strDateTime, "yyyy-MM-dd hh:mm:ss");
	}

	// 获取两个时间相差秒数
	public static Long timeDifference(Date date) {
		long end = date.getTime();
		long start = new Date().getTime();
		return (start - end) / 1000;
	}

	public static String getSerialVersionUID() {
		SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		return fmt.format(new Date()) + new Random().nextInt(1000000);
	}
	
	public static int getTotalSeconds(){
		return (int)(System.currentTimeMillis()/1000);
	}

	/**
	 * 获取某年某月的最后一天
	 * @param year
	 * @param month
	 * @return
	 */
	public static String getLastDayOfMonth(int year,int month)
	{
		Calendar cal = Calendar.getInstance();
		//设置年份
		cal.set(Calendar.YEAR,year);
		//设置月份
		cal.set(Calendar.MONTH, month-1);
		//获取某月最大天数
		int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
		//设置日历中月份的最大天数
		cal.set(Calendar.DAY_OF_MONTH, lastDay);
		//格式化日期
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String lastDayOfMonth = sdf.format(cal.getTime());

		return lastDayOfMonth;
	}

	/**
	 * 得到某年某月第一天
	 * @param year
	 * @param month
	 * @return
	 */
	public static String getFisrtDayOfMonth(int year,int month)
	{
		Calendar cal = Calendar.getInstance();
		//设置年份
		cal.set(Calendar.YEAR,year);
		//设置月份
		cal.set(Calendar.MONTH, month-1);
		//获取某月最小天数
		int firstDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
		//设置日历中月份的最小天数
		cal.set(Calendar.DAY_OF_MONTH, firstDay);
		//格式化日期
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String firstDayOfMonth = sdf.format(cal.getTime());

		return firstDayOfMonth;
	}
	public static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private static boolean isOverlap(String startdate1, String enddate1,String startdate2, String enddate2) {
		Long leftStartDate = null;
		Long leftEndDate = null;
		Long rightStartDate = null;
		Long rightEndDate = null;
		try {
			leftStartDate = format.parse(startdate1).getTime();
			leftEndDate = format.parse(enddate1).getTime();
			rightStartDate = format.parse(startdate2).getTime();
			rightEndDate = format.parse(enddate2).getTime();
			System.out.println(leftStartDate);
			System.out.println(leftEndDate);
			System.out.println(rightStartDate);
			System.out.println(rightEndDate);
		} catch (ParseException e) {
			return false;
		}
		return (rightStartDate>=leftStartDate && rightEndDate <=leftEndDate)||
				(rightStartDate<=leftStartDate && rightEndDate >=leftEndDate)||
				(rightEndDate<=leftStartDate && rightEndDate >=leftEndDate);
	}


	
	/**
	 * 获取指定偏移几天的的日期
	 * @param pos 偏移天数，0表示当天，-1表示前一天，1表示明天
	 * @return
	 */
	public static String getDayYmd(int pos) {

		Calendar Cal = Calendar.getInstance();
		Cal.setTime(new Date());
		Cal.add(Calendar.HOUR_OF_DAY, pos*24);
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PATTERN_DATE);
		return simpleDateFormat.format(Cal.getTime());

	}
	
	/**
	 * 获取指定偏移几天的的日期
	 * @param pos 偏移天数，0表示当天，-1表示前一天，1表示明天
	 * @return
	 */
	public static Date getDayOfDiff(Date oriDate,int pos) {
		Date date = null;
		Calendar Cal = Calendar.getInstance();
		Cal.setTime(oriDate);
		Cal.add(Calendar.DATE, pos);
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PATTERN_DATE);
		try {
			date = simpleDateFormat.parse(simpleDateFormat.format(Cal.getTime()));
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
		return date;
	}
	
	/**
	 * 获取指定偏移几天的的日期
	 * @param pos 偏移天数，0表示当天，-1表示前一天，1表示明天
	 * @return
	 */
	public static Date getMonthOfDiff(Date oriDate,int pos) {
		Date date = null;
		Calendar Cal = Calendar.getInstance();
		Cal.setTime(oriDate);
		Cal.add(Calendar.MONTH, pos);
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PATTERN_DATE);
		try {
			date = simpleDateFormat.parse(simpleDateFormat.format(Cal.getTime()));
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
		return date;
	}
	
	/**
	 * 当前时间的偏移月和天数
	 * @param monthPos 偏移月
	 * @param period 偏移天
	 * @return
	 */
	public static Date getDateOfPos(int monthPos,int period){
			Date date = null;
		Calendar Cal = Calendar.getInstance();
		Cal.setTime(getFirstDayOfMonth(Cal));
		Cal.add(Calendar.MONTH, monthPos);
		//默认从第一天开始，所以period要减少1
		Cal.add(Calendar.DATE, period-1);
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PATTERN_DATE);
		try {
			date = simpleDateFormat.parse(simpleDateFormat.format(Cal.getTime()));
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
		return date;
	}

	/**
	 * 判断今天、昨天、前天 或者更早
	 * @param createTime
	 * @return
	 */
	public static String judgeTime(String createTime){
		try {
			String ret = "";
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			long create = sdf.parse(createTime).getTime();
			Calendar now = Calendar.getInstance();
			long ms  = 1000*(now.get(Calendar.HOUR_OF_DAY)*3600+now.get(Calendar.MINUTE)*60+now.get(Calendar.SECOND));//毫秒数
			long ms_now = now.getTimeInMillis();
			if(ms_now-create<ms){
				ret = "今天";
			}else if(ms_now-create<(ms+24*3600*1000)){
				ret = "昨天";
			}else if(ms_now-create<(ms+24*3600*1000*2)){
				ret = "前天";
			}else{
				ret= "更早";
			}
			return ret;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}


	/** 
     * 给定的时间，按照分钟进行偏移 
     *  
     * @param date 给定的时间 
     * @param offset 偏移量 
     * @return 偏移后的时间 
     */  
    public static Date modifiyMinute(Date date, int offset)  
    {  
          
        return modifiyDate(date, Calendar.MINUTE, offset);  
    }  
      
    /** 
     * 给定的时间，按照秒进行偏移 
     *  
     * @param date 给定的时间 
     * @param offset 偏移量 
     * @return 偏移后的时间 
     */  
    public static Date modifiySecond(Date date, int offset)  
    {  
          
        return modifiyDate(date, Calendar.SECOND, offset);  
    }  
      
    /** 
     * 给定的时间，按照小时进行偏移 
     *  
     * @param date 给定的时间 
     * @param offset 偏移量 
     * @return 偏移后的时间 
     */  
    public static Date modifiyHour(Date date, int offset)  
    {  
          
        return modifiyDate(date, Calendar.HOUR_OF_DAY, offset);  
    }  
      
    /** 
     * 给定的时间，按照年份进行偏移 
     *  
     * @param date 给定的时间 
     * @param offset 偏移量 
     * @return 偏移后的时间 
     */  
    public static Date modifiyYear(Date date, int offset)  
    {  
          
        return modifiyDate(date, Calendar.YEAR, offset);  
    }  
      
    /** 
     * 给定的时间，按照月份进行偏移 
     *  
     * @param date 给定的时间 
     * @param offset 偏移量 
     * @return 偏移后的时间 
     */  
    public static Date modifiyMonth(Date date, int offset)  
    {  
          
        return modifiyDate(date, Calendar.MONTH, offset);  
    }  
      
    /** 
     * 给定的时间，按照天数进行偏移 
     *  
     * @param date 给定的时间 
     * @param offset 偏移量 
     * @return 偏移后的时间 
     */  
    public static Date modifiyDayOfMonth(Date date, int offset)  
    {  
          
        return modifiyDate(date, Calendar.DAY_OF_MONTH, offset);  
    }  
      
    /** 
     * 给定时间，按照指定的类型进行偏移 
     *  
     * @param date 给定的时间 
     * @param calendarFiled 指定的偏移类型（年 或 月 或 日 等等） 
     * @param offset 偏移量 
     * @return 偏移后的时间 
     */  
    private static Date modifiyDate(Date date, int calendarFiled, int offset)  
    {  
        if (date == null)  
        {  
            throw new IllegalArgumentException("传递的时间有误");  
        }  
        Calendar calendar = Calendar.getInstance();  
        calendar.setTime(date);  
        calendar.add(calendarFiled, offset);  
        return new Date(calendar.getTimeInMillis());  
    }

	/**
	 * 获取指定日期后天数
	 * @param specifiedDay 指定日期
	 * @param dayNum 天数
	 * @return
	 */
	public static String getSpecifiedDayAfter(String specifiedDay,int dayNum){
		Calendar c = Calendar.getInstance();
		Date date=null;
		try {
			date = new SimpleDateFormat("yy-MM-dd").parse(specifiedDay);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		c.setTime(date);
		int day=c.get(Calendar.DATE);
		c.set(Calendar.DATE, day + dayNum);

		String dayAfter=new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
		return dayAfter;
	}
	/**
	 * @return 返回指定月份的最后一天的59分59秒
	 */
	public static Date getLastMonthOfDate(Date date) {
		Calendar para = Calendar.getInstance(java.util.Locale.CHINA);
		para.setTime(date);
		para.set(Calendar.DATE, para.getActualMaximum(Calendar.DAY_OF_MONTH));
		para.set(Calendar.HOUR_OF_DAY, 23);
		para.set(Calendar.MINUTE, 59);
		para.set(Calendar.SECOND, 59);
		return para.getTime();
	}

	public static String jsonDate(String strDate, String pattern) {
		if (strDate == null || strDate.equals("")) {
			throw new RuntimeException("str date null");
		}
		if (pattern == null || pattern.equals("")) {
			pattern = DateUtil.PATTERN_STANDARD;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		Date date = null;
		try {
			date = sdf.parse(strDate);
			SimpleDateFormat sdf1 = new SimpleDateFormat(pattern);
			strDate=sdf1.format(date);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
		return strDate;
	}
	

}